package service

import (
	"fmt"
	"niu-video/app/consts"
	"niu-video/app/model"
	"niu-video/app/repository"
	"niu-video/app/utils"
	"niu-video/pkg/logger"
	"niu-video/pkg/redis"
	"strconv"
)

var CommentService = newCommentService()

func newCommentService() *commentService {
	return &commentService{}
}

type commentService struct {
}

// 创建评论
func (u *commentService) Create(request model.CommentDto, userId int64) error {

	err := repository.CommentRepository.Create(&model.Comment{
		UserID:   userId,
		VideoID:  request.VideoID,
		ParentId: request.ParentId,
		Content:  request.Content,
	})
	u.comment(request.VideoID)
	return err
}

func (u *commentService) GetCommentList(videoId int64) ([]model.CommentVo, error) {
	comments := repository.CommentRepository.GetVideoCommentList(videoId)
	commentVos := make([]model.CommentVo, 0)
	for _, comment := range comments {
		vo, err := u.convertComment(comment)
		if err != nil {
			return nil, err
		}
		commentVos = append(commentVos, vo)
	}
	return commentVos, nil
}

func (u *commentService) Delete(commentId int64, videoId int64) {
	repository.CommentRepository.Delete(commentId)
	u.unComment(videoId)
}

func (u *commentService) convertComment(comment model.Comment) (model.CommentVo, error) {
	user := repository.UserRepository.Get(comment.UserID)
	child, err := u.GetCommentChildren(comment.CommentID)
	if err != nil {
		return model.CommentVo{}, err
	}
	return model.CommentVo{
		CommentID: comment.CommentID,
		Author: model.Author{
			UserId:   user.UserID,
			Nickname: user.Nickname,
			Username: user.Username,
			Avatar:   user.Avatar,
		},
		Content:  comment.Content,
		Time:     utils.DateDiff(comment.CreateTime),
		Children: child,
	}, nil
}
func (u *commentService) GetCommentChildren(parentId int64) ([]model.CommentVo, error) {
	comments := repository.CommentRepository.GetChildren(parentId)
	commentVos := make([]model.CommentVo, len(comments))
	for i, comment := range comments {
		vo, err := u.convertComment(comment)
		if err != nil {
			return nil, err
		}
		commentVos[i] = vo
	}
	return commentVos, nil
}

// 增加评论数
func (l *commentService) comment(videoId int64) {
	redis.Redis.Increment(fmt.Sprintf("%s:%d", consts.REDIS_COMMENT_COUNTER_PREFIX, videoId))
}

// 减少评论数
func (l *commentService) unComment(videoId int64) {
	redis.Redis.Decrement(fmt.Sprintf("%s:%d", consts.REDIS_COMMENT_COUNTER_PREFIX, videoId))
}

func (l *commentService) CommentCount(videoId int64) int64 {
	cntStr := redis.Redis.Get(fmt.Sprintf("%s:%d", consts.REDIS_COMMENT_COUNTER_PREFIX, videoId))
	if cntStr == "" {
		return 0
	}
	cnt, err := strconv.ParseInt(cntStr, 10, 64)
	if err != nil {
		logger.ErrorString("comment", "CommentCount", err.Error())
		return 0
	}
	return cnt
}
